package com.example.communitypro.service.impl;

import com.example.communitypro.mapper.*;
import com.example.communitypro.pojo.ChatList;
import com.example.communitypro.pojo.Message;
import com.example.communitypro.pojo.Notification;
import com.example.communitypro.pojo.UserInformation;
import com.example.communitypro.service.ChatService;
import com.example.communitypro.util.result.Result;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private MessageDao messageDao;
    @Autowired
    private ChatListDao chatListDao;
    @Autowired
    private UserActionsMapper UserActionsMapper;
    @Autowired
    private UserInformationMapper userInformationMapper;
    @Autowired
    private NotificationMapper notificationMapper;


    @Override
    public String selectAssociation(Integer sender, Integer receiver) {
        return null;
    }

    public int[] getRelationShip(Integer sender, Integer receiver, List<Integer> senderFollowed,List<Integer> receiverFollowed) {
        int senderType = 0;
        int receiverType = 0;
        if (senderFollowed.contains(receiver) && receiverFollowed.contains(sender)) {
            senderType = 4;
            receiverType = 4;
        } else if (senderFollowed.contains(receiver) && !receiverFollowed.contains(sender)) {
            senderType = 1;
            receiverType = 2;
        } else if (!senderFollowed.contains(receiver) && receiverFollowed.contains(sender)) {
            senderType = 2;
            receiverType = 1;
        } else if (!senderFollowed.contains(receiver) && !receiverFollowed.contains(sender)) {
            senderType = 0;
            receiverType = 0;
        } else if (receiver ==-1) {
            senderType = 3;
            receiverType = 0;
        } else {
            senderType = 0;
            receiverType = 0;
        }
        return new int[]{senderType, receiverType};
    }

    @Override
    public int isFirstChat(Integer sender, Integer receiver) {
        try {
            Date javaDate = new Date();
            long time = javaDate.getTime();
            Timestamp stamp = new Timestamp(time);
            ChatList chatList = chatListDao.getChatList(sender, receiver);
            if (chatList == null) {
                ChatList senderChat = new ChatList(1, sender, receiver, 1, 0, 1, 0, stamp);
                ChatList receiverChat = new ChatList(1, receiver, sender, 1, 0, 1, 0, stamp);
                chatListDao.insertChatList(senderChat);
                chatListDao.insertChatList(receiverChat);
                return senderChat.getListId();
            } else if (chatList.getStatus() == 0) {
                chatList.setStatus(1);
                chatListDao.updateChatList(chatList);
                return chatList.getListId();
            } else
                return chatList.getListId();

        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    public void saveMessage(Message message) {
        try {
            if (userInformationMapper.selectByPrimaryKey(message.getSender()) != null && userInformationMapper.selectByPrimaryKey(message.getSender()) != null) {
                ChatList chatList = chatListDao.getChatList(message.getReceiver(), message.getSender());
                //用户给对方发消息则代表自己一定位于聊天窗口,则将自己该listId所有的消息已读;
                chatListDao.setUnRead(message.getListId());
                //前面判断用户是否在线,后面是判断用户当前是否在对应的聊天窗口.
                if (userInformationMapper.getStatus(message.getSender()) == 1 &&
                        userInformationMapper.getListId(message.getReceiver()) == chatList.getListId()) {
                    //符合条件则立马设置当前消息已读并设置对方之前的消息已读
                    message.setIsRead(1);
                    messageDao.setMessageReadByList(message.getListId());
                    chatListDao.setUnRead(chatList.getListId());
                } else {
                    //不符合条件则将对方的chatList的unread加一
                    chatList.setUnread(chatList.getUnread() + 1);
                    chatListDao.updateChatList(chatList);
                }
                messageDao.insertMessage(message);

                /**
                 * lsl
                 */
//                notificationMapper.insert(new Notification(message.getSender(),4,new Date(),message.getReceiver(),0,"你有一条私信"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Result getSenderChatList(Integer sender) {
        try {
            List<ChatList> chatLists = chatListDao.getChatListBySender(sender);
            List<Integer> ids=chatLists.stream().map(u -> u.getListId()).collect(Collectors.toList());
            List<Integer> senderFollowed = UserActionsMapper.getUserFollow(sender,1).stream().map(u -> u.getUserNo()).collect(Collectors.toList());
            List<Integer> receiverFollowed = UserActionsMapper.getFollowUser(sender,1).stream().map(u -> u.getUserNo()).collect(Collectors.toList());
            Map<Integer,ChatList> map=chatLists.parallelStream().collect(Collectors.toMap(ChatList::getReceiver, v -> v));
            Map<Integer, Message> latestMessage=new HashMap<>();
            List<Message> messages = messageDao.getMessageBySender(sender);
            Collections.sort(messages, Comparator.comparing(Message::getSendTime, (t1, t2) -> t1.compareTo(t2)));
            for (Message m:messages
                 ) {
                //判断最新的消息是否是自己发的
                if(ids.contains(m.getListId())){
                    latestMessage.put(m.getListId(),m);
                }
                //不是则去找对应的接收者然后找到自己和该接收者的ListId放入 LatestMessage
                else{
                    latestMessage.put(map.get(m.getSender()).getListId(),m);
                }
            }
            Map<Integer, UserInformation> users = chatListDao.getUserBySender(sender).parallelStream().collect(Collectors.toMap(UserInformation::getUserNo, v -> v));
            for (ChatList s : chatLists) {
                s.setType(getRelationShip(sender, s.getReceiver(),senderFollowed,receiverFollowed)[0]);
                if(users.get(s.getReceiver())!=null)
                s.setIsOnline(users.get(s.getReceiver()).getUserOnline());
                else continue;
            }
            return Result.ok().data("chatList",chatLists).data("users",users).data("latestMessage",latestMessage);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error().message("未知错误:"+e.toString());
        }
    }

    @Override
    public Result getRecentChatRecords(Integer sender, Integer receiver, Integer amount) {
        try {
            List<Message> messageList=messageDao.getMessageBySenderAndReceiver(sender,receiver,amount);
            for (Message m:messageList
                 ) {
                if(m.getSender().equals(sender))
                    m.setIsMine(true);
                else m.setIsMine(false);
            }

            Collections.sort(messageList, Comparator.comparing(Message::getSendTime, (t1, t2) -> t1.compareTo(t2)));

            return Result.ok().message("查询成功").data("messageList",messageList);
        }catch (Exception e){

        }
        return null;
    }

    @Override
    public Result getUnreadTotalNumber(String username) {
        return null;
    }

    @Override
    public Result createChatList(int sender, int receiver) {
        return null;
    }

    @Override
    public void resetWindows(String username) {

    }

    @Override
    public Result setUnRead(int listId) {
        try {
            ChatList chatList=chatListDao.getChatListById(listId);
            ChatList other= chatListDao.getChatList(chatList.getReceiver(),chatList.getSender());
            messageDao.setMessageReadByList(other.getListId());
            chatListDao.setUnRead(listId);
            return Result.ok().message("设置已读成功");
        }catch (Exception e){
            return Result.error().message("未知错误:"+e.toString());
        }
    }
}
